package canglang.monitor.core.codelookup.taglib;

import org.apache.taglibs.standard.lang.support.ExpressionEvaluatorManager;
import org.springframework.context.ApplicationContext;
import static org.springframework.web.context.support.WebApplicationContextUtils.getWebApplicationContext;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import canglang.monitor.core.codelookup.model.CodeModel;
import canglang.monitor.core.codelookup.service.CodeLookupMgr;

/**
 * A custom tag library to get the code description from the code.
 */
@SuppressWarnings("unchecked")
public class CodeDescTag extends TagSupport {

    /**
     * Delimiter for filterParams attribute.
     */
    private static final String FILTER_PARAMS_DELIMITER = ",";

    /**
     * The code-type in codelookup-config.xml.
     */
    private String codeType;

    /**
     * The code identifier
     */
    private String codeId;

    /**
     * The sql-filter name in codelookup-config.xml.
     */
    private String filterName;

    /**
     * One or more filter params.  Use "," as delimiter.
     * eg. "Code1,Code2"
     */
    private String filterParams;

    /**
     * Lookup from codelookup-config.properties instead of from database
     * if this parameter is set to 'true'.
     */
    private String lookupFromFile;


    public String getCodeType() {
        return codeType;
    }

    public void setCodeType(String codeType) {
        this.codeType = codeType;
    }

    public String getCodeId() {
        return codeId;
    }

    public void setCodeId(String codeId) {
        this.codeId = codeId;
    }

    public String getFilterName() {
        return filterName;
    }

    public void setFilterName(String filterName) {
        this.filterName = filterName;
    }

    public String getFilterParams() {
        return filterParams;
    }

    public void setFilterParams(String filterParams) {
        this.filterParams = filterParams;
    }

    public String getLookupFromFile() {
        return lookupFromFile;
    }

    public void setLookupFromFile(String lookupFromFile) {
        this.lookupFromFile = lookupFromFile;
    }

    public int doEndTag() throws JspException
    {
        // Evaluate EL Expression

        if (codeType != null) {
            codeType = (String) ExpressionEvaluatorManager.evaluate("codeType", codeType, String.class, this, pageContext);
        }

        if (codeId != null) {
            codeId = (String) ExpressionEvaluatorManager.evaluate("codeId", codeId, String.class, this, pageContext);
        }

        if (filterName != null) {
            filterName = (String) ExpressionEvaluatorManager.evaluate("filterName", filterName, String.class, this, pageContext);
        }

        if (filterParams != null) {
            filterParams = (String) ExpressionEvaluatorManager.evaluate("filterParams", filterParams, String.class, this, pageContext);
        }

        if (lookupFromFile != null) {
        	lookupFromFile = (String) ExpressionEvaluatorManager.evaluate("lookupFromFile", lookupFromFile, String.class, this, pageContext);
        }



        String codeDesc = null;

        ApplicationContext context = getWebApplicationContext(this.pageContext.getServletContext());
        CodeLookupMgr codeLookupManager = (CodeLookupMgr) context.getBean("codeLookupManager");

            CodeModel codeTO = null;

            if (!useFilter()) {
                codeTO = codeLookupManager.getCode(codeType, codeId);
            } else {
                // Get the first code from the list
                List codeList = codeLookupManager.getCodeList(codeType, filterName, getFilterParamsList());
                if (codeList.size() > 0) {
                    codeTO = (CodeModel) codeList.get(0);
                }
            }

            if (codeTO != null) {
                codeDesc = codeTO.getCodeDesc();
            }



        if (codeDesc != null) {
        	codeDesc=codeDesc.replaceAll("<","&lt;").replaceAll(">","&gt;");
            JspWriter out = pageContext.getOut();
            try {
                out.print(codeDesc);
            } catch (Exception e) {
                e.printStackTrace();
                throw new JspException("Error printing code description for " +
                        "Code Type=" + codeType + ", Code Id=" + codeId, e);
            }
        }

        return EVAL_PAGE;
    }

    /**
     * Get a <code>List</code> of filer params using <code>filterParams</code>
     * attribute and <code>FILTER_PARAMS_DELIMITER</code> as delimiter.
     *
     * @return filter params in a <code>List</code>.
     */
    private List getFilterParamsList() {
        List paramsList = new ArrayList();
        if (filterParams != null && !filterParams.equals("")) {
            StringTokenizer token = new StringTokenizer(filterParams,
                    FILTER_PARAMS_DELIMITER);
            while (token.hasMoreTokens()) {
                paramsList.add(token.nextToken());
            }
        }
        return paramsList;
    }

    /**
     * If no filter name then return false else return true.
     *
     * @return true if use filter otherwise false.
     */
    private boolean useFilter() {
        return (filterName != null && !filterName.equals(""));
    }
}